﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

using G.Runtime;
using G.Runtime.Actions;
using GameControls;
using G.Model;

namespace GameRuntimeControls
{
    public class BoardShapeDisplayerPT : BoardShapeDisplayer
    {
        private readonly GameDisplayerPT _GameDisplayer;
        private readonly GameSpace _Game;
        private readonly BoardShape _BoardShape;
        
        public BoardShapeDisplayerPT(
            GameDisplayerPT displayer, BoardShape shape,
            BoardShapeContainer shapeContainer, GameSpace pGame)
            : base(displayer, shape.Location, shape, shapeContainer)
        {
            _GameDisplayer = displayer;
            _Game = pGame;
            _BoardShape = shape;
            this.Shape.MouseClick += new MouseEventHandler(this.Shape_MouseClick);
            _Game.Elements.ElementPositionChangedEvent += this.OnElementPositionChanged;
            _Game.Elements.PropertyChangedEvent += delegate(GameElement subject) 
            {
                DisplayIcon();
            };
            
            DisplayIcon();
        }

        public override void DisplayIcon()
        {
            GameElement e = GetElement();
            
            Image image = null;
            string icon = GameDisplayer.GameDef.GlobalDef.DefaultIcon;
            
            if (_Game.Globals.TopImages.Contains(base.Location))
            {
                image = _Game.Globals.TopImages[base.Location].Image;
            }
            else
            {
                if (e != null && e.Icon != "")
                {
                    icon = e.Icon;
                }
                if (icon == null)
                {
                    icon = "";
                }
                
                Dictionary<string, Image> list = 
                    base.GameDisplayer.ShapeContainer
                    .GameUserControl.ImageDictionary;
                if (list != null && icon != "")
                {
                    foreach (string key in list.Keys) 
                    {
                        if (key.ToLower().Contains(icon.ToLower()))
                        {
                            image = list[key];
                        }
                    }
                }
            }
            
            if (e != null && _Game.Players.Contains(e.Player))
            {
                GamePlayer player = _Game.Players[e.Player];
                Shape.BackColor = player.Color;
            }
            else
            {
                Shape.BackColor = GameDisplayer.DEFAULT_BACK_COLOR;
            }
            
            if (image != null)
            {
                Shape.BackgroundImage = image;
                Shape.Text = "";
            }
            else
            {
                Shape.BackgroundImage = null;
                
                if (e != null)
                {
                    Shape.Text = e.Text;
                }
                else
                {
                    Shape.Text = "";
                }
            }
            
            Shape.Invalidate();
        }

        private void Shape_MouseClick(Object target, EventArgs e)
        {
            BoardShapeContainer sender = (BoardShapeContainer)target;
            BoardShape shape = sender.HeighlightedShape;
            GameLocation location = sender.ToGameLocation(shape.Location);
            
            GameElement subject = null;
            if (_GameDisplayer.Game.Elements.Contains(location))
            {
                subject = _GameDisplayer.Game.Elements[location];
            }
            
            {
                GameClickEventArgs args = 
                    _GameDisplayer.Game.FireClickEvent(location, subject);
                if (args.handled)
                {
                    return;
                }
            }
            
            if (subject != null)
            {
                subject = _GameDisplayer.Game.Elements[location];
                
                ElementEventArgs args =
                    _GameDisplayer.Game.Elements.RaiseClickEvent(subject);
                if (args.handled) 
                {
                    return;
                }
            }

            if (subject is GameElement)
            {
                if (!_Game.Controller.ElementsReadyToMove.Contains(subject))
                {
                    subject = null;
                }
            }

            if (_GameDisplayer.Game.Elements.Actions.Contains(location))
            {
                GameElementAction action = _GameDisplayer.Game.Elements.Actions[location];
                action.Execute(_GameDisplayer.Game);
            }
            else if (subject is GameElement)
            {
                _GameDisplayer.Game.Elements.Actions.Clear();
                GameAction[] actions = subject.Actions.ToArray();
                foreach (GameAction action in actions)
                {
                    if (action is GameElementAction)
                    {
                        GameElementAction a = (GameElementAction)action;
                        _GameDisplayer.Game.Elements.Actions.Add(a);
                    }
                }
                
//                ButtonPanel painter = _GameDisplayer.ButtonPanel;
//                painter.Clear();
//                foreach(GameTask task in subject.Game.GameTasks)
//                {
//                    painter.Add(_Game, task, subject);
//                }
//                
//                ActiveObject.Object = subject;
            }
            else
            {
//                _GameDisplayer.Game.Elements.Actions.Clear();
            }
        }

        private GameElement GetElement()
        {
            GameElement e = null;
            if (this._GameDisplayer.Game.Elements.Contains(Location))
            {
                e = this._GameDisplayer.Game.Elements[Location];
            }

            return e;
        }

        private void OnElementPositionChanged(GameLocation location)
        {
            if (base.Location == location)
            {
                DisplayIcon();
            }
        }

        private void OnPropertyChanged(object o, PropertyChangedEventArgs args)
        {
            DisplayIcon();
        }

    }

}
